package com.yunji.framework_template.common.zookeeper;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author fenglibin
 *
 */
@Service
@Slf4j
public class ZKCuratorUtil {

	// ZK客户端
	@Resource(name = "curatorFramework")
	private CuratorFramework curatorFramework;

	public ZKCuratorUtil(CuratorFramework curatorFramework) {
		this.curatorFramework = curatorFramework;
	}

	/**
	 * 初始化操作
	 */
	@PostConstruct
	public void init() {
		log.info("Use zookeeper as the zookeeper's name space.");
		// 使用命名空间
		curatorFramework = curatorFramework.usingNamespace("zookeeper");
	}

	/**
	 * 获取Zookeeper客户端连接
	 * 
	 * @return
	 */
	public CuratorFramework getCuratorFramework() {
		return curatorFramework;
	}
	
	public ZooKeeper getZooKeeper() throws Exception {
		return getCuratorFramework().getZookeeperClient().getZooKeeper();
	}

	/**
	 * 判断ZK是否连接
	 * 
	 * @return
	 */
	public boolean isStarted() {
		return curatorFramework != null 
				&& (curatorFramework.getState() == CuratorFrameworkState.STARTED);
	}

	/**
	 * 判断是否已经停止
	 * 
	 * @return
	 */
	public boolean isStoped() {
		return curatorFramework == null 
				|| (curatorFramework.getState() == CuratorFrameworkState.STOPPED);
	}
	
	/**
	 * 获取独占锁<br>
	 * 使用在Zookeeper创建临时节点的机制，如果创建成功，则认为其获取锁成功，<br>
	 * 如果创建节点失败，则认为锁获取失败。<br>
	 * @param currentLockPath 待创建的锁节点
	 * @return 获取独占锁是否成功
	 */
	public boolean getExclusiveLock(String currentLockPath) {
		String nowDate = String.valueOf(System.currentTimeMillis());
		try {
			//在Zookeeper创建指定的临时节点，如果节点已经存在了，会抛出异常
			getZooKeeper().create(currentLockPath, nowDate.getBytes(), 
					Ids.READ_ACL_UNSAFE, CreateMode.EPHEMERAL);
		} catch (Exception e) {
			return false;
		}
		return true;
	}
}